/***************************************************************************\
 * The Mattise Kernel														*
 * Copyright 2007 Matthew Iselin											*
 * Licensed under the GPL													*
 *																			*
 * syscall.cc																*
 *																			*
 * Implementation of system calls, all based on interrupt 0x80 (128d)		*
 *																			*
\***************************************************************************/

// Includes
#include <system.h>
#include <stdio.h>
#include <task.h>
#include <io.h>
#include <memory.h>
#include <syscall.h>
#include <string.h>
#include <console.h>

// Constants

// simple stuff
#define SYSCALL_EXIT		0
#define SYSCALL_PRINTSTR	1
#define SYSCALL_PRINTCHAR	2

// device drivers use these
#define SYSCALL_INSTDEVICE	3
#define SYSCALL_INSTFUNCTS	4
#define SYSCALL_GETDEVID	5
#define SYSCALL_GETDEVNAME	6
#define SYSCALL_DESTROYDEV	7
#define SYSCALL_DUMPDEVS	8

// device/file i/o
#define SYSCALL_OPEN		9
#define SYSCALL_CLOSE		10
#define SYSCALL_FSTAT		11
#define SYSCALL_ISATTY		12
#define SYSCALL_LINK		13
#define SYSCALL_LSEEK		14
#define SYSCALL_READ		15
#define SYSCALL_STAT		16
#define SYSCALL_UNLINK		17
#define SYSCALL_WRITE		18

// environment control
#define SYSCALL_ENVIRON		19

// process control
#define SYSCALL_EXECVE		20
#define SYSCALL_FORK		21
#define SYSCALL_GETPID		22
#define SYSCALL_KILL		23
#define SYSCALL_TIMES		24
#define SYSCALL_WAIT		25

// heap space
#define SYSCALL_SBRK		26

// Functions

void SysCall( struct regs* r )
{
	// what function?
	switch( r->eax )
	{
		case SYSCALL_EXIT:
		
			// kill the current process and reschedule
			kill( currpid() );
			resched();
			break;
		
		case SYSCALL_PRINTSTR:
		
			// print the string in ESI
			{
				char* esi = (char*) r->esi;
				cons.Output( esi );
			}
			break;
		
		case SYSCALL_PRINTCHAR:
		
			// print the character in ESI
			kprintf( "%c", r->esi );
			break;
		
		case SYSCALL_INSTDEVICE:
		
			// install the device
			r->ebx = InstallDevice( (char*) r->esi, r->ecx, r->edx );
			break;
			
		case SYSCALL_INSTFUNCTS:
		
			// install the functions
			r->ebx = InstallFunctions( r->ecx, *((INSTFUNCDATA*) r->esi) );
			break;
		
		case SYSCALL_GETDEVID:
		
			// get the device id
			r->ebx = GetDeviceID( r->ecx );
			break;
		
		case SYSCALL_GETDEVNAME:
		
			// get the device name
			{
				char* tmp = (char*) kmalloc( 64 );
				GetDeviceName( r->ecx, tmp );
				r->esi = (uint_t) tmp;
			}
			break;
			
		case SYSCALL_DESTROYDEV:
		
			// destroy the device
			DestroyDevice( r->ecx );
			break;
		
		case SYSCALL_DUMPDEVS:
		
			// dump the device list
			DumpDevices();
			break;
		
		case SYSCALL_OPEN:
		
			// open the device
			r->ebx = open( (char*) r->esi, r->ecx );
			break;
		
		case SYSCALL_CLOSE:
		
			// closes a device
			r->ebx = close( r->ecx );
			break;
		
		case SYSCALL_FSTAT:
		
			// not implemented yet
			break;
		
		case SYSCALL_ISATTY:
		
			// not implemented yet
			break;
		
		case SYSCALL_LINK:
		
			// not implemented yet
			break;
		
		case SYSCALL_LSEEK:
		
			// seeks in a device
			r->ebx = lseek( r->ecx, r->edx, r->ebx );
			break;
		
		case SYSCALL_READ:
		
			// reads from a device
			r->ebx = read( r->ecx, (char*) r->esi, r->edx );
			break;
		
		case SYSCALL_STAT:
		
			// not implemented yet
			break;
		
		case SYSCALL_UNLINK:
		
			// not implemented yet
			break;
		
		case SYSCALL_WRITE:
		
			// writes to a device
			//kprintf( "writing %s\n", (char*) r->esi );
			r->ebx = write( r->ecx, (char*) r->esi, r->edx );
			break;
		
		case SYSCALL_ENVIRON:
		
			// not implemented yet
			break;
		
		case SYSCALL_EXECVE:
		
			// not implemented yet
			break;
		
		case SYSCALL_FORK:
		
			// not implemented yet
			break;
		
		case SYSCALL_GETPID:
		
			// gets the current process id
			r->ebx = currpid();
			break;
		
		case SYSCALL_TIMES:
		
			// not implemented yet
			break;
		
		case SYSCALL_WAIT:
		
			// not implemented yet
			break;
		
		case SYSCALL_SBRK:
		
			// returns the address of the 'end' symbol in ebx
			extern char end;
			r->ebx = (uint_t) &end;
			break;
	}
}
